home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- VGLFONTS.C
-
- Routines to add bitmapped font capabilities. Read the comments for each
- routine for instructions on how to use them. They're pretty straight
- forward.
-
- Mark
- morley@camosun.bc.ca
- *****************************************************************************/
-
- #include <stdio.h>
- #include <dos.h>
- #include <dir.h>
- #include "vgl.h"
-
- static VGLFONT header; /* The current font info. */
- static unsigned char buffer[4096]; /* All bitmaps for a font must fit */
- /* within this buffer. This does */
- /* not include the header data, so */
- /* all the fonts I included with */
- /* this package will fit just fine. */
-
- static int cx = 0; /* The current X and Y position of */
- static int cy = 0; /* the invisible "cursor". This is */
- /* where the next character will be */
- /* drawn. X is the leftmost column */
- /* of the character, but Y is *NOT* */
- /* the topmost row! Y is the row */
- /* that lines up with the char's */
- /* *BASELINE* */
-
- static int color = 15; /* Default color for text is white */
- static int shcolor = 1; /* Shadow color is blue */
- static int uncolor = 1; /* Underline color is blue */
- static int bold = 0; /* Bolding is off */
- static int shadow = 0; /* Shadows are off */
- static int italic = 0; /* Italics are off */
- static int underline = 0; /* Underlining is off */
-
- /*****************************************************************************
- Turns bolding off.
- *****************************************************************************/
- vglBoldOff()
- {
- bold = 0;
- return;
- }
-
- /*****************************************************************************
- Turns bolding on.
- *****************************************************************************/
- vglBoldOn()
- {
- bold = 1;
- return;
- }
-
- /*****************************************************************************
- Returns the current X position. Remember that X represents the column that
- will match the leftmost column of the next character.
- *****************************************************************************/
- vglGetX()
- {
- return cx;
- }
-
- /*****************************************************************************
- Turns the current Y position. Remember that Y represents the row that will
- match the BASELINE of the next character!
- *****************************************************************************/
- vglGetY()
- {
- return cy;
- }
-
- /*****************************************************************************
- Goto X,Y. See the above two functions for an explanation of the X and Y
- meanings.
- *****************************************************************************/
- vglGotoXY( int x, int y )
- {
- cx = x;
- cy = y;
- if( cy < header.vspace )
- cy = header.vspace;
- return;
- }
-
- /*****************************************************************************
- Turns italics on. I'm afraid my "italics" are not the nicest. I simply
- shear the character to the right, one pixel per scan line. This is
- perhaps a little *too* italicised.
- *****************************************************************************/
- vglItalicsOn()
- {
- italic = 1;
- return;
- }
-
- /*****************************************************************************
- Turns italics off.
- *****************************************************************************/
- vglItalicsOff()
- {
- italic = 0;
- return;
- }
-
- /*****************************************************************************
- Loads a font from disk. If the font can be read it returns 1, else it
- returns 0. Only one font can be in memory at a time, but since fonts are
- generally small due to the font file format, you can load them pretty
- quickly.
- *****************************************************************************/
- vglLoadFont( char* font )
- {
- FILE* fp;
-
- fp = fopen( font, "rb" );
- if( !fp )
- return 0;
- fread( &header, sizeof(VGLFONT), 1, fp );
- fread( buffer, header.data, 1, fp );
- fclose( fp );
- return 1;
- }
-
- /*****************************************************************************
- The kernel of the font engine. Messy Marvin time. Oh well, whaddya expect
- for a 2 hour hack? Anyway, this is the routine that actually draws a
- character on the screen at the current X,Y location. It advances the X,Y
- position and wraps across and down the screen as necessary. At the end of
- the screen it will wrap back to the top left corner. If you try and
- display a carriage return or newline, they will work just like they would
- in a printf() call.
-
- The routine works by drawing the character into a tiny buffer, then calling
- the vglPutSprite() routine to display it. This means that you cannot use
- the color 0 for text, underlines, or shadows because it will be transparent.
- If you want black shadows, use another palette entry!
-
- This routine, along with the font file format, was created in about 2
- hours. I HAVEN'T FULLY TESTED IT!!! It works for me (so far), and
- hopefully you will find it useful.
-
- WARNING: This ain't no speed demon! I was more interested in having a
- small font file format. I also wanted the font to take up minimal RAM
- when loaded. These means more processing.
-
- I hope to add other text effects (eg: outline), but who knows?
- *****************************************************************************/
- vglPutc( int c )
- {
- register x, y;
- int bit, oy;
- unsigned char* off;
- unsigned char rast[2048];
- unsigned char* b;
- int h, w, rw, o, oo;
- int wid, hit;
-
- if( header.flags & FONT_UPPERCASE && c >= 'a' && c <= 'z' )
- c -= 32;
- if( c < 33 )
- {
- switch( c )
- {
- case '\r' : cx = 0;
- break;
- case '\n' : cy += header.vspace;
- break;
- case ' ' : if( underline )
- {
- for( y = 1; y <= underline; y++ )
- vglLine( cx, cy + y, cx + header.wswid, cy + y, uncolor );
- }
- cx += header.wswid;
- break;
- }
- return;
- }
- if( header.chwid[c] == 0 )
- return;
- h = header.chhit[c];
- w = header.chwid[c];
- if( italic )
- oo = h / 2;
- else
- oo = 0;
- o = oo;
- rw = w + bold + shadow + o;
- if( cx + rw > 319 )
- {
- cx = 0;
- cy += header.vspace;
- }
- if( cy > 199 )
- {
- cx = 0;
- cy = header.vspace;
- }
- off = buffer + header.choff[c];
- oy = cy - header.chbas[c] + 1;
- memset( rast, 0, 2048 );
- b = rast;
- wid = rw;
- hit = h + shadow;
- if( underline )
- {
- for( y = 1; y <= underline; y++ )
- vglLine( cx, cy + y, cx + rw + header.hspace, cy + y, uncolor );
- }
- for( y = 0; y < h; y++ )
- {
- bit = 1;
- b += o;
- for( x = 0; x < w; x++, bit <<= 1 )
- {
- if( bit == 256 )
- {
- bit = 1;
- off++;
- }
- if( *off & bit )
- {
- *b = color;
- if( shadow )
- *(b + shadow + rw * shadow) = shcolor;
- if( bold )
- {
- *(b + 1) = color;
- if( shadow )
- *(b + 1 + shadow + rw * shadow) = shcolor;
- }
- }
- b++;
- }
- b += bold + shadow + (oo - o);
- if( italic && (y & 1) )
- o--;
- off++;
- }
- vglPutSprite( cx, oy, wid, hit, (char far*)rast );
- cx += w + bold;
- cx += header.hspace;
- return;
- }
-
- /*****************************************************************************
- Displays a string. To display a formatted string (like printf) you should
- first use sprintf to print into a buffer, then pass that buffer to vglPuts
- *****************************************************************************/
- vglPuts( char* s )
- {
- while( *s )
- vglPutc( *s++ );
- return;
- }
-
- /*****************************************************************************
- Sets the shadow color. This does *not* turn shadows on!
- *****************************************************************************/
- vglShadowColor( int c )
- {
- shcolor = c;
- return;
- }
-
- /*****************************************************************************
- Turns shadows off.
- *****************************************************************************/
- vglShadowOff()
- {
- shadow = 0;
- return;
- }
-
- /*****************************************************************************
- Turns shadows on. The "depth" of the shadow is specified in pixels.
- Normally a value of 1 or 2 looks good.
- *****************************************************************************/
- vglShadowOn( int s )
- {
- if( s > 10 )
- s = 10;
- else if( s < 1 )
- s = 1;
- shadow = s;
- return;
- }
-
- /*****************************************************************************
- Sets the text color.
- *****************************************************************************/
- vglTextColor( int c )
- {
- color = c;
- return;
- }
-
- /*****************************************************************************
- Sets the underline color.
- *****************************************************************************/
- vglUnderlineColor( int c )
- {
- uncolor = c;
- return;
- }
-
- /*****************************************************************************
- Turns on underlining. The thickness of the underlining is specified in
- pixels. A value of 1 or 2 usually looks good.
- *****************************************************************************/
- vglUnderlineOn( int n )
- {
- if( n > 10 )
- n = 10;
- else if( n < 1 )
- n = 1;
- underline = n;
- return;
- }
-
- /*****************************************************************************
- Turns off underlining.
- *****************************************************************************/
- vglUnderlineOff()
- {
- underline = 0;
- return;
- }
-
-